#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
	int sno;		//学号
	char sex[3];	//性别
	char sname[20]; //姓名
	float grade;	//成绩
	struct node *nextNode;
} Node;

/**
 * [createNode 创建节点返回指针]
 * @return [description]
 */
static Node *createNode()
{
	Node *node = (Node *)calloc(1, sizeof(Node));
	node->nextNode = NULL;
	return node;
}
/**
 * [insert 插入节点]
 * @param  h [头节点指针]
 * @param  s [要插入的节点]
 * @return   [头节点]
 */
static Node *insert(Node *h, Node *s)
{
	if (h == NULL)
	{ //插入第一个节点时 没有头节点
		printf("插入成功\n");
		return s; // s作为头节点
	}
	if (s->sno < h->sno)
	{					 // s节点的学号比头节点小
		s->nextNode = h; // s作为头节点
		printf("插入成功\n");
		return s;
	}

	Node *tempNode = h;		  //中间变量 用于遍历
	Node *preNode = tempNode; //中间变量的前一个节点
	while (tempNode != NULL)
	{
		if (s->sno > tempNode->sno)
		{ //要插入的节点的学号比当前节点大
			preNode = tempNode;
			tempNode = tempNode->nextNode;
			continue;
		}
		//插入到中间
		preNode->nextNode = s;
		s->nextNode = tempNode;
		break;
	}
	if (tempNode == NULL)
	{ //插入的节点比已有的节点都大
		preNode->nextNode = s;
	}
	printf("插入成功\n");
	return h;
}
/**
 * [locate 根据学号查找目标节点]
 * @param  h  [头节点指针]
 * @param  no [学号]
 * @return    [目标节点,没找到返回NULL]
 */
Node *locate(Node *h, int no)
{
	Node *tempNode = h; //中间变量 用于遍历
	for (; tempNode != NULL && tempNode->sno != no; tempNode = tempNode->nextNode)
	{
	}
	if (tempNode == NULL)
	{
		printf("查无此学生\n");
	}
	return tempNode;
}

/**
 * [deleteNode 根据学号删除节点]
 * @param  h  [头节点]
 * @param  no [学号]
 * @return    [头节点]
 */
Node *deleteNode(Node *h, int no)
{
	Node *tempNode = h;		  //中间变量 用于遍历
	Node *preNode = tempNode; //中间变量的前一个节点
	if (no == h->sno)
	{
		tempNode = h->nextNode;
		free(h);
		return tempNode;
	}

	while (tempNode != NULL)
	{
		if (no != tempNode->sno)
		{
			preNode = tempNode;
			tempNode = tempNode->nextNode;
			continue;
		}
		preNode->nextNode = tempNode->nextNode;
		free(tempNode);
	}
	return h;
}

/**
 * [printNode 打印节点]
 * @param tempNode [节点]
 */
void printNode(Node *tempNode)
{
	if (tempNode == NULL)
	{
		return;
	}
	printf("%d \t%s \t%s \t%f\n", tempNode->sno, tempNode->sname, tempNode->sex, tempNode->grade);
}
/**
 * [printLink 打印所有节点]
 * @param h [头节点]
 */
void printLink(Node *h)
{
	printf("学号  \t姓名  \t性别  \t成绩\n");
	Node *tempNode = h; //中间变量 用于遍历
	while (tempNode != NULL)
	{
		printNode(tempNode);
		tempNode = tempNode->nextNode;
	}
}

/**
 * [freeLink 释放空间]
 * @param h [头节点]
 */
void freeLink(Node *h)
{
	Node *freeNode = h;	   //要释放的节点
	Node *nextNode = NULL; //要释放的节点的下一个节点
	while (freeNode != NULL)
	{
		nextNode = freeNode->nextNode;
		printf("释放学号为%d的空间\n", freeNode->sno);
		free(freeNode);
		freeNode = nextNode;
	}
}

/**
 * [main 主函数]
 * @return [description]
 */
int main19()
{
	Node *head = NULL; //头节点
	while (1)
	{
		Node *node = createNode(); //创建节点
		printf("请输入学号:");
		scanf("%d", &(node->sno));
		if (node->sno == -1)
		{
			free(node);
			break;
		}
		printf("%d\n", node->sno);
		printf("\n请输入姓名:");
		scanf("%s", &(node->sname));
		printf("%s\n", node->sname);

		printf("\n请输入性别:");
		scanf("%s", &(node->sex));
		printf("%s\n", node->sex);

		printf("\n请输入成绩:");
		scanf("%f", &(node->grade));
		printf("%f\n", node->grade);
		head = insert(head, node);
	}
	printf("\n======================您输入的学生信息如下=======================\n");
	printLink(head);

	int sno; //学号
	printf("\n请输入要查找到的学生的学号:");
	scanf("%d", &sno);
	printNode(locate(head, sno));

	printf("\n请再次输入要查找到的学生的学号:");
	scanf("%d", &sno);
	printNode(locate(head, sno));

	printf("\n请输入要删除的学生的学号:");
	scanf("%d", &sno);
	head = deleteNode(head, sno);
	printf("\n======================删除后的学生信息如下=======================\n");
	printLink(head);
	printf("======================释放所有节点=======================\n");
	freeLink(head);
	printf("释放空间完成\n");
	return 0;
}